package com.wusir.cordova.http;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Log;

/**
 * Http 插件
 * 
 * @author 吴Sir 
 * @date 16-05-20.
 * 
 */
public class DlHttp extends CordovaPlugin {

	public static final String TAG = "DlHttp";
	public static final String ACTION_REQUEST = "request";

	private CallbackContext callback;

	@Override
	public boolean execute(String action, JSONArray args,
			CallbackContext callbackContext) throws JSONException {
		Log.d(TAG, "action=" + action);
		this.callback = callbackContext;
		
		final JSONObject data = args.getJSONObject(0);
		System.out.println(data);
		
		final String url = getString(data, "url");
		final String type = getString(data, "type", "GET");
		final Integer timeout = getInt(data, "timeout");
		final String dataType = getString(data, "dataType");
		
		new AsyncTask<Void, Void, String>() {

			@Override
			protected void onPostExecute(String result) {
				System.out.println(result);
				callback(result, dataType);
			}

			@Override
			protected String doInBackground(Void... p) {
				// TODO Auto-generated method stub
				String result = null;
				if ("POST".equals(type)) {
					final JSONObject params = getJSONObject(data, "params");
					result = postRequest(url, params, timeout);
				} else if ("GET".equals(type)) {
					result = getRequest(url, timeout);
				}
				return result;
			}

		}.execute();

		return true;
	}

	private void callback(String result, String dataType) {
		if (result != null) {
			if ("text".equals(dataType)) {
				callback.success(result);
			} else {
				if ("jsonp".equals(dataType)) {
					result = jsonpToJson(result);
				}
				try {
					callback.success(new JSONObject(result));
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} else {
			callback.error("request failed");
		}
	}

	/**
	 * jsonp格式数据格式化为json格式数据
	 * 
	 * @param data
	 * @return
	 */
	private String jsonpToJson(String data) {
		// TODO Auto-generated method stub
		try {
			int start = data.indexOf("(") + 1;
			int end = data.lastIndexOf(")");
			String jsonStr = data.substring(start, end);
			return jsonStr;
		} catch (IndexOutOfBoundsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NullPointerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * GET请求
	 * 
	 * @param strUrl
	 * @param timeout
	 * @return
	 */
	private String getRequest(final String strUrl, Integer timeout) {
		// TODO Auto-generated method stub
		String result = null;
		try {
			URL url = new URL(strUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			String session = getSession();
			if (session != null) {
				conn.setRequestProperty("Cookie", session);
			}
			saveSession(conn.getHeaderField("Set-Cookie"));
			
			if (timeout == null) {
				timeout = 5000;
			}
			conn.setConnectTimeout(timeout);
			conn.setReadTimeout(timeout);
			
			InputStreamReader reader = new InputStreamReader(conn.getInputStream());
			BufferedReader bufferReader = new BufferedReader(reader);
			result = "";
			String readLine = "";
			while ((readLine = bufferReader.readLine()) != null) {
				result += readLine;
			}
			reader.close();
			conn.disconnect();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * POST 请求
	 * 
	 * @param strUrl
	 * @param paramsObj		参数
	 * @param timeout
	 * @return
	 */
	private String postRequest(final String strUrl, JSONObject paramsObj, Integer timeout) {
		// TODO Auto-generated method stub
		String result = null;
		try {
			URL url = new URL(strUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			String session = getSession();
			if (session != null) {
				conn.setRequestProperty("cookie", session);
			}
			if (timeout == null) {
				timeout = 5000;
			}
			conn.setConnectTimeout(timeout);
			conn.setReadTimeout(timeout);
			
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			conn.setUseCaches(false);
			conn.connect();
			
			String params = getParams(paramsObj);
			System.out.println(params);
			
			DataOutputStream output = new DataOutputStream(conn.getOutputStream());
			output.writeBytes(params);
			output.flush();
			output.close();
			
			InputStreamReader reader = new InputStreamReader(conn.getInputStream());
			BufferedReader bufferReader = new BufferedReader(reader);
			result = "";
			String readLine = "";
			while ((readLine = bufferReader.readLine()) != null) {
				result += readLine;
			}
			reader.close();
			conn.disconnect();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	private String getParams(JSONObject paramsObj) {
		// TODO Auto-generated method stub
		String params = "";
		try {
			Iterator<String> keys = paramsObj.keys();
			while (keys.hasNext()) {
				String key = keys.next();
				params += "&" + key + "=" + paramsObj.getString(key);
			}
			if (params.length() > 0) {
				params = params.substring(1);
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return params;
	}

	private String getSession() {
		// TODO Auto-generated method stub
		SharedPreferences preferences = cordova.getActivity().getSharedPreferences("http", Activity.MODE_PRIVATE);
		return preferences.getString("session", null);
	}
	
	private void saveSession(String cookieval) {
		if (cookieval != null) {
			String sessionid = cookieval.substring(0, cookieval.indexOf(";"));
			SharedPreferences.Editor editor = cordova.getActivity().getSharedPreferences("http", Activity.MODE_PRIVATE).edit();
			editor.putString("session", sessionid);
			editor.commit();
		}
	}

}
